<?php
/**
 * User authentication session
 *
 * @link http://webappkit.net
 * @package webappkit
 * @subpackage engine
 * @author J.Ducastel <nospam0@ducastel.name>
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
 * @property string $id primary key and cookie value, = md5(token.user_id.start_date)
 * @property string $token random token
 * @property mixed $user_id
 * @property Datetimebean $start_date
 * @property Datetimebean $end_date expiration or manual closing date
 */
class UserAuthSession extends DataBean {

    /**
     * factory to be used by UserAuthSessions
     * @param mixed $user_id
     * @param int $duration in hours, default to 14 days
     * @return UserAuthSession
     */
    public static function factory($user_id, $duration=336) {
        $token = self::generateToken();
        $start_date = DateTimeBean::now();
        $end_date = clone($start_date);
        $end_date->addSeconds($duration * 3600);
        $session = new UserAuthSession(array(
            'token' => $token
            , 'user_id' => $user_id
            , 'start_date' => $start_date
            , 'end_date' => $end_date));
        $session->setValidId();
        return $session;
    }

    /**
     * generate a random token
     * @return string
     */
    public static function generateToken() {
        return substr(md5(uniqid(rand(), true)), 5, 15);
    }

    /**
     * sets a valid id
     * @return bool
     */
    public function setValidId() {
        $this->id = md5($this->token.$this->user_id.$this->start_date->toMysqlDateTime());
        return true;
    }

    /**
     * tells if authentication session is structurally valid
     * checks that id = md5(token.user_id.start_date)
     * @return bool
     */
    public function isValid() {
        return $this->id == md5($this->token.$this->user_id.$this->start_date->toMysqlDateTime());
    }

    /**
     * tells if session has expired
     * @return bool
     */
    public function isClosed() {
        return !$this->end_date->isFuture();
    }

    /**
     * get user id
     * @return mixed usually integer
     */
    public function getUserId() {
        return $this->user_id;
    }

    /**
     * sets session end_date to now
     * @return bool
     */
    public function close() {
        $this->end_date = DateTimeBean::now();
        return $this->isClosed();
    }

    protected $start_date;
    protected function _start_date_inputFilter($value) {
        return $this->_toDateTimeBean($value);
    }

    protected $end_date;
    protected function _end_date_inputFilter($value) {
        return $this->_toDateTimeBean($value);
    }
}